package server.request;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.HttpContent;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpObject;
import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.handler.codec.http.cookie.Cookie;
import io.netty.handler.codec.http.cookie.ServerCookieDecoder;
import io.netty.util.CharsetUtil;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author cg
 * @date 2023/6/7 13:23
 */
public class HttpRequest {
    private ChannelHandlerContext ctx;

    private io.netty.handler.codec.http.HttpRequest request;
    /**
     * 请求方式
     */
    private String method;

    /**
     * 请求路径
     */
    private String url;
    /**
     * 请求参数列表
     */
    private Map<String, String> parameterMap = new HashMap<>();

    /**
     * 请求体参数列表
     */
    private Map<String, String> requestBodyMap;

    private InputStream inputStream;

    private Map<String, String> headers;

    private Map<String, String> cookies;

    public HttpRequest(ChannelHandlerContext ctx, HttpObject msg) {
        this.ctx = ctx;
        this.request = (io.netty.handler.codec.http.HttpRequest) msg;
        this.method = request.method().name();
        this.url = request.uri();
        if (url.contains("?")) {
            url = url.substring(0, url.lastIndexOf("?"));
        }
        //解析cookies集合
        loadCookies();
        //解析请求头信息
        loadHeaders();
        //解析请求路径参数
        loadParameterMap();

    }

    public String getCookie(String key) {
        return this.cookies.get(key);
    }

    public Map<String, String> getCookies() {
        return cookies;
    }

    public void loadCookies() {
        this.cookies = new HashMap<>();
        String cookieString = this.request.headers().get(HttpHeaderNames.COOKIE);
        if (cookieString != null) {
            Set<Cookie> cookies = ServerCookieDecoder.STRICT.decode(cookieString);
            for (Cookie cookie : cookies) {
                // 获取 Cookie 信息
                String name = cookie.name();
                String value = cookie.value();
                this.cookies.put(name, value);
            }
        }
    }

    public Map<String, String> getHeaders() {
        return headers;
    }

    public String getHeader(String headerName) {
        return this.headers.get(headerName);
    }

    public void loadHeaders() {
        this.headers = new HashMap<>();
        for (Map.Entry<String, String> header : request.headers()) {
            headers.put(header.getKey(), header.getValue());
        }
    }

    public InputStream getInputStream() {
        return inputStream;
    }

    public void setInputStream(InputStream inputStream) {
        this.inputStream = inputStream;
    }

    public String getPathParameter(String parameterName) {
        return parameterMap.get(parameterName);
    }

    public String getBodyParameter(String parameterName) {
        return requestBodyMap.get(parameterName);
    }

    public Map<String, String> getRequestBodyMap() {
        return requestBodyMap;
    }

    public void setRequestBodyMap(HttpObject msg) {
        HttpContent content = (HttpContent) msg;
        ByteBuf buf = content.content();
        String requestBody = buf.toString(CharsetUtil.UTF_8);

        this.requestBodyMap = new HashMap<>();
        for (String keyValue : requestBody.split("&")) {
            String[] pair = keyValue.split("=");
            if (pair.length == 2) {
                this.requestBodyMap.put(pair[0], pair[1]);
            }
        }
    }

    public String getMethod() {
        return method;
    }

    public void setMethod(String method) {
        this.method = method;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public Map<String, String> getParameterMap() {
        return parameterMap;
    }

    public void loadParameterMap() {
        this.parameterMap = new HashMap<>();
        Map<String, List<String>> parameters = new QueryStringDecoder(request.uri()).parameters();
        for (String key : parameters.keySet()) {
            parameterMap.put(key, parameters.get(key).get(0));
        }
    }
}
